package com.pap.gateway.config;

import com.pap.gateway.config.security.handler.RestAuthenticationAccessDeniedHandler;
import com.pap.gateway.config.security.handler.RestBasicServerAuthenticationEntryPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.ServerAuthenticationEntryPoint;
import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler;

/**
 * security 统一鉴权
 *
 * 注意当前默认 uua 的链接可以不进行过滤， 注意 uua 可以直接透传(uua 含登录注册等逻辑)
 *
 * 注意两个地方：  SecurityWebFilterChain webFluxSecurityFilterChain、 AuthenticationWebFilter authenticationWebFilter 两个方法里面的 URL 权限校验
 */
@EnableWebFluxSecurity
public class WebSecurityConfig {

    @Autowired
    private com.pap.gateway.config.security.core.PapSecurityContextRepository papSecurityContextRepository;

    @Bean
    public ServerAccessDeniedHandler restAuthenticationAccessDeniedHandler() {
        return new RestAuthenticationAccessDeniedHandler();
    }

    @Bean
    public ServerAuthenticationEntryPoint restBasicServerAuthenticationEntryPoint() {
        return new RestBasicServerAuthenticationEntryPoint();
    }

    @Bean
    SecurityWebFilterChain webFluxSecurityFilterChain(ServerHttpSecurity http) throws Exception {
        http.csrf().disable().formLogin().disable().httpBasic().disable().logout().disable()
                .securityContextRepository(papSecurityContextRepository)
                .authorizeExchange()
                // TODO 这里进行动态修改
                .pathMatchers("/uua/**").permitAll()
                .pathMatchers("/oauth/**").permitAll()
                .pathMatchers("/business/token").permitAll()
                .pathMatchers("/rbac/token").permitAll()
                .pathMatchers("/rbac/test").permitAll()
                .anyExchange().authenticated()
                .and().exceptionHandling().accessDeniedHandler(restAuthenticationAccessDeniedHandler())
                .and().exceptionHandling().authenticationEntryPoint(restBasicServerAuthenticationEntryPoint());
                //.addFilterAt(authenticationWebFilter(), SecurityWebFiltersOrder.AUTHENTICATION);

        return http.build();
    }

}